package lion.formail.reader.accountcfg;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.apache.poi.poifs.filesystem.DirectoryEntry;
import org.apache.poi.poifs.filesystem.DocumentEntry;
import org.apache.poi.poifs.filesystem.DocumentInputStream;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

/**
 * Account.stg是Microsoft的复合文档类型的文件 只是按照复合文档类型对Account.stg进行针对性的解析
 */
public class ComReader {

	public byte[] getBoxByteArray(File accountstg) throws IOException {

		InputStream is = new FileInputStream(accountstg);
		POIFSFileSystem fs = null;

		fs = new POIFSFileSystem(is);
		DirectoryEntry root = fs.getRoot();
		DirectoryEntry ver30Dir = (DirectoryEntry) root.getEntry("Ver30");
		DocumentEntry boxTreeEntry = (DocumentEntry) ver30Dir.getEntry("BoxTree.cfg");

		DocumentInputStream dis = new DocumentInputStream(boxTreeEntry);

		byte[] bytes = new byte[dis.available()];

		dis.read(bytes);
		dis.close();

		return bytes;

	}

	public static int getReverseBytesInt(byte[] bb, int index) {

		return ((((bb[index + 3] & 0xff) << 24) | ((bb[index + 2] & 0xff) << 16) | ((bb[index + 1] & 0xff) << 8) | ((bb[index + 0] & 0xff) << 0)));
	}

	public static void copyByteArray(byte[] dest, byte[] src, int offset, int length) {

		for (int i = 0; i < length; i++) {
			dest[i] = src[offset + i];
		}
	}

	/**
	 * 旧的不完全的方法 // byte[] content; byte[] header; int[] sat;
	 * 
	 * byte[] intBuf = new byte[4];
	 * 
	 * 
	 * content = new byte[(int) accountstg.length()];
	 * 
	 * FileInputStream fis = new FileInputStream(accountstg); fis.read(content);
	 * fis.close(); // 头 header = new byte[512]; copyByteArray(header, content,
	 * 0, 512);
	 * 
	 * byte[] flag = new byte[8];
	 * 
	 * copyByteArray(flag, header, 0, 8);
	 * 
	 * //校验文件，前8个字节 byte[] h = new byte[] { (byte) 0xd0, (byte) 0xcf, 0x11,
	 * (byte) 0xe0, (byte) 0xa1, (byte) 0xb1, 0x1a, (byte) 0xe1 };
	 * 
	 * for (int i = 0; i < 8; i++) {
	 * 
	 * if (flag[i] != h[i]) {
	 * 
	 * throw new IOException("文件格式不正确"); } } // SAT总共占用的Sector
	 * copyByteArray(intBuf, header, 44, 4); int SATCount =
	 * getReverseBytesInt(intBuf, 0); // 第一个 目录所在的Sector intBuf = new byte[4];
	 * copyByteArray(intBuf, header, 48, 4); int firstDirectorySectoryId =
	 * getReverseBytesInt(intBuf, 0); // 第一个SSAT所在的SectorID intBuf = new
	 * byte[4]; copyByteArray(intBuf, header, 60, 4); int firstSSATSID =
	 * getReverseBytesInt(intBuf, 0); // SSAT所占扇区总数 intBuf = new byte[4];
	 * copyByteArray(intBuf, header, 64, 4); int SSATCount =
	 * getReverseBytesInt(intBuf, 0); // MSAT扇区中的内容 byte[] satChainBuf = new
	 * byte[436]; copyByteArray(satChainBuf, header, 76, 436);
	 * 
	 * int[] satChain = new int[109]; for (int i = 0, j = 0; i < 109; i++, j +=
	 * 4) {
	 * 
	 * byte[] buf = new byte[4]; copyByteArray(buf, satChainBuf, j, 4); int y =
	 * getReverseBytesInt(buf, 0); satChain[i] = y; } // SAT所在的Sector列表 sat =
	 * new int[SATCount]; for (int i = 0; i < SATCount; i++) { sat[i] =
	 * satChain[i]; } // SAT中的内容 byte[] satContent = new byte[512 * SATCount];
	 * for (int i = 0; i < SATCount; i++) { for (int j = 0; j < 512; j++) {
	 * satContent[i * 512 + j] = content[(sat[i] + 1) * 512 + j]; } } //
	 * SAT中SID内容 int[] SIDChain = new int[satContent.length / 4];
	 * 
	 * for (int i = 0, j = 0; i < SIDChain.length; i++, j += 4) { byte[] buf =
	 * new byte[4]; copyByteArray(buf, satContent, j, 4); int y =
	 * getReverseBytesInt(buf, 0); SIDChain[i] = y; }
	 * 
	 * int leastIndex = 0; // 得到目录SID链 List directoryChain = new ArrayList();
	 * for (int i = firstDirectorySectoryId;;) { if (i == leastIndex + 1) {
	 * leastIndex = i; } if (SIDChain[i] == -4 || SIDChain[i] == -3 ||
	 * SIDChain[i] == -1) { i++; continue; } directoryChain.add(i);
	 * 
	 * if (SIDChain[i] == -2) { break; } i = SIDChain[i]; } // 得到SSAT 的SID链 List
	 * SSATChain = new ArrayList(); for (int i = firstSSATSID;;) {
	 * 
	 * if (i == leastIndex + 1) { leastIndex = i; }
	 * 
	 * if (SIDChain[i] == -4 || SIDChain[i] == -3 || SIDChain[i] == -1) { i++;
	 * continue; } SSATChain.add(i); if (SIDChain[i] == -2) { break; } i =
	 * SIDChain[i]; } // 得到剩下的流的SIDChain List streamSIDChain = new ArrayList();
	 * for (int i = leastIndex + 1;;) { if (SIDChain[i] == -4 || SIDChain[i] ==
	 * -3 || SIDChain[i] == -1) { i++; continue; } streamSIDChain.add(i); if
	 * (SIDChain[i] == -2) { break; } i = SIDChain[i]; } //
	 * 得到流的SIDChain所代表的所有的Sector的内容 byte[] streamContentBuf = new byte[0];
	 * 
	 * for (int i = 0; i < streamSIDChain.size(); i++) { int x = (Integer)
	 * streamSIDChain.get(i); byte[] temp = new byte[512]; copyByteArray(temp,
	 * content, (x + 1) * 512, 512); streamContentBuf = concat(streamContentBuf,
	 * temp); } // 得到目录流所代表的所有的Sector的内容 byte[] dirbuf = new byte[0]; for (int i
	 * = 0; i < directoryChain.size(); i++) { int x = (Integer)
	 * directoryChain.get(i); byte[] temp = new byte[512];
	 * 
	 * copyByteArray(temp, content, (x + 1) * 512, 512);
	 * 
	 * dirbuf = concat(dirbuf, temp); } // 得到目录 BoxTree.cfg 目录大小严格为128B /**
	 * 00000f80h: 42 00 6F 00 78 00 54 00 72 00 65 00 65 00 2E 00
	 * ;B.o.x.T.r.e.e... 00000f90h: 63 00 66 00 67 00 ; c.f.g.
	 * 
	 * byte[] dirtemp = null; int did = 0; String dirname = new String(new
	 * byte[] { 0x42, 0x00, 0x6f, 0x00, 0x78, 0x00, 0x54, 0x00, 0x72, 0x00,
	 * 0x65, 0x00, 0x65, 0x00, 0x2e, 0x00, 0x63, 0x00, 0x66, 0x00, 0x67, 0x00 },
	 * "UTF-8"); while (true) {
	 * 
	 * dirtemp = new byte[128]; copyByteArray(dirtemp, dirbuf, did * 128, 128);
	 * 
	 * int size = dirtemp[64] & 0xff;
	 * 
	 * byte[] dirName = new byte[size - 2]; copyByteArray(dirName, dirtemp, 0,
	 * dirName.length); String name = new String(dirName, "UTF-8"); if
	 * (dirname.equals(name)) { break; } did++; }
	 * 
	 * intBuf = new byte[4]; copyByteArray(intBuf, dirtemp, 116, 4); int
	 * firstDid = getReverseBytesInt(intBuf, 0); // 得到流大小 intBuf = new byte[4];
	 * copyByteArray(intBuf, dirtemp, 120, 4); int boxsize =
	 * getReverseBytesInt(intBuf, 0); // 得到SSAT中所有Sector的全部内容 byte[] ssatcontent
	 * = new byte[0]; for (int i = 0; i < SSATChain.size(); i++) { int x =
	 * (Integer) SSATChain.get(i); byte[] temp = new byte[512];
	 * copyByteArray(temp, content, (x + 1) * 512, 512); ssatcontent =
	 * concat(ssatcontent, temp); } // 得到SSAT中的链 int[] ssatChain = new
	 * int[ssatcontent.length / 4]; for (int i = 0, j = 0; i <
	 * ssatcontent.length / 4; i++, j += 4) { byte[] buf = new byte[4];
	 * copyByteArray(buf, ssatcontent, j, 4); int y = getReverseBytesInt(buf,
	 * 0); ssatChain[i] = y; } // 得到Boxtree所在的链 List boxChain = new ArrayList();
	 * 
	 * int i = firstDid; while (true) {
	 * 
	 * if (ssatChain[i] == -4 || ssatChain[i] == -3 || ssatChain[i] == -1) {
	 * i++; continue; }
	 * 
	 * boxChain.add(i); if (ssatChain[i] == -2) { break; } i = ssatChain[i]; }
	 * // 读取boxTree的内容 byte[] boxcontent = new byte[0]; for (i = 0; i <
	 * boxChain.size(); i++) { int x = (Integer) boxChain.get(i); byte[] temp =
	 * new byte[64]; copyByteArray(temp, streamContentBuf, x * 64, 64);
	 * boxcontent = concat(boxcontent, temp); }
	 * System.out.println("boxSize:"+boxsize); System.out.println("boxcontent:"
	 * + boxcontent.length);
	 * 
	 * byte[] usedCotent = new byte[boxsize]; // 异常在这里出现
	 * copyByteArray(usedCotent, boxcontent, 0, boxsize);
	 * 
	 * return usedCotent;
	 */

}
